home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / proc / link.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  2.4 KB  |  126 lines

  1. /*
  2.  *  linux/fs/proc/link.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  *  /proc link-file handling code
  7.  */
  8.  
  9. #include <asm/segment.h>
  10.  
  11. #include <linux/errno.h>
  12. #include <linux/sched.h>
  13. #include <linux/fs.h>
  14. #include <linux/minix_fs.h>
  15. #include <linux/stat.h>
  16.  
  17. static int proc_readlink(struct inode *, char *, int);
  18. static int proc_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  19.  
  20. /*
  21.  * links can't do much...
  22.  */
  23. struct inode_operations proc_link_inode_operations = {
  24.     NULL,            /* no file-operations */
  25.     NULL,            /* create */
  26.     NULL,            /* lookup */
  27.     NULL,            /* link */
  28.     NULL,            /* unlink */
  29.     NULL,            /* symlink */
  30.     NULL,            /* mkdir */
  31.     NULL,            /* rmdir */
  32.     NULL,            /* mknod */
  33.     NULL,            /* rename */
  34.     proc_readlink,        /* readlink */
  35.     proc_follow_link,    /* follow_link */
  36.     NULL,            /* bmap */
  37.     NULL,            /* truncate */
  38.     NULL            /* permission */
  39. };
  40.  
  41. static int proc_follow_link(struct inode * dir, struct inode * inode,
  42.     int flag, int mode, struct inode ** res_inode)
  43. {
  44.     unsigned int pid, ino;
  45.     struct task_struct * p;
  46.     int i;
  47.  
  48.     *res_inode = NULL;
  49.     if (dir)
  50.         iput(dir);
  51.     if (!inode)
  52.         return -ENOENT;
  53.     ino = inode->i_ino;
  54.     pid = ino >> 16;
  55.     ino &= 0x0000ffff;
  56.     iput(inode);
  57.     for (i = 0 ; i < NR_TASKS ; i++)
  58.         if ((p = task[i]) && p->pid == pid)
  59.             break;
  60.     if (i >= NR_TASKS)
  61.         return -ENOENT;
  62.     inode = NULL;
  63.     switch (ino) {
  64.         case 4:
  65.             inode = p->pwd;
  66.             break;
  67.         case 5:
  68.             inode = p->root;
  69.             break;
  70.         case 6:
  71.             inode = p->executable;
  72.             break;
  73.         default:
  74.             switch (ino >> 8) {
  75.                 case 1:
  76.                     ino &= 0xff;
  77.                     if (ino < NR_OPEN && p->filp[ino])
  78.                         inode = p->filp[ino]->f_inode;
  79.                     break;
  80.                 case 2:
  81.                     ino &= 0xff;
  82.                     { int j = ino;
  83.                       struct vm_area_struct * mpnt;
  84.                       for(mpnt = p->mmap; mpnt && j >= 0;
  85.                           mpnt = mpnt->vm_next){
  86.                         if(mpnt->vm_inode) {
  87.                           if(j == 0) {
  88.                         inode = mpnt->vm_inode;
  89.                         break;
  90.                           };
  91.                           j--;
  92.                         }
  93.                       }
  94.                     };
  95.             }
  96.     }
  97.     if (!inode)
  98.         return -ENOENT;
  99.     *res_inode = inode;
  100.     inode->i_count++;
  101.     return 0;
  102. }
  103.  
  104. static int proc_readlink(struct inode * inode, char * buffer, int buflen)
  105. {
  106.     int i;
  107.     unsigned int dev,ino;
  108.     char buf[64];
  109.  
  110.     i = proc_follow_link(NULL, inode, 0, 0, &inode);
  111.     if (i)
  112.         return i;
  113.     if (!inode)
  114.         return -EIO;
  115.     dev = inode->i_dev;
  116.     ino = inode->i_ino;
  117.     iput(inode);
  118.     i = sprintf(buf,"[%04x]:%u", dev, ino);
  119.     if (buflen > i)
  120.         buflen = i;
  121.     i = 0;
  122.     while (i < buflen)
  123.         put_fs_byte(buf[i++],buffer++);
  124.     return i;
  125. }
  126.